package com.tea.service.impl;

import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.service.WxPayService;
import com.tea.common.config.TeawineConfig;
import com.tea.common.core.domain.AjaxResult;
import com.tea.common.model.WxUser;
import com.tea.common.utils.SecurityUtils;
import com.tea.common.utils.StringUtils;
import com.tea.funct.domain.*;
import com.tea.funct.domain.vo.InUpDetailsVo;
import com.tea.funct.service.*;
import com.tea.service.WxApiService;
import com.tea.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.*;

@Slf4j
@Service
public class WxApiServiceImpl implements WxApiService {

    @Autowired
    private ISysUserService userService;
    @Autowired
    private ITeaMemberService teaMemberService;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private ITeaTopupService teaTopupService;
    @Autowired
    private ITeaRenewService teaRenewService;
    @Autowired
    private ITeaDetailsService teaDetailsService;
    @Autowired
    private ITeaPriceDetailsService teaPriceDetailsService;
    @Autowired
    private ITeaRewardRecordService teaRewardRecordService;
    @Autowired
    private ITeaAdvertisConfigService teaAdvertisConfigService;
    @Autowired
    private ITeaProductService teaProductService;

    @Override
    public AjaxResult createWxOrder(Long renewId) {
        //记录微信订单
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        StringBuffer orderId = new StringBuffer();
        orderId.append(dateTimeFormatter.format(LocalDateTime.now()));
        orderId.append(new Random().nextInt(9999));
        log.info("微信订单{} 创建中....", orderId);
        String type = "createWxOrder";//类型
        Long userId = SecurityUtils.getUserId();
        WxUser wxUser = userService.selectWxUserByUserId(userId);
        String openId = wxUser.getOpenId();
        Long memberId = wxUser.getMemberId();
        TeaRenew teaRenew = teaRenewService.selectTeaRenewById(renewId);

        TeaTopup teaTopup = new TeaTopup();
        teaTopup.setOrderId(orderId.toString());
        teaTopup.setOrderAmount(teaRenew.getBenefitsAmount());
        teaTopup.setOrderStatus("1");
        teaTopup.setMemberId(memberId);
        teaTopup.setRenewId(teaRenew.getId());
        teaTopup.setCreateTime(new Date());
        teaTopup.setRemark(teaRenew.getTitle());
        teaTopupService.insertTeaTopup(teaTopup);
        Integer moneyPoint = teaTopup.getOrderAmount().multiply(new BigDecimal(100)).intValue(); // 金额单位为分
        //向微信服务器提交申请
        try {
            Map<String, Object> orderResp = this.createWxOrderToWxService(openId, teaTopup.getOrderId(), moneyPoint, teaTopup.getRemark(), type);
            return AjaxResult.success(orderResp);
        } catch (Exception e) {
            log.error("发起微信支付出现异常:{}", e.getMessage());
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    @Override
    @Transactional
    public String wxOrderNotify(String xmlData) {
        try {
            log.info("接收微信订单支付后反馈信息: {}", xmlData);
            final WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
            if (null != notifyResult && StringUtils.isNotBlank(notifyResult.getTransactionId())) {
                //更新用户订单状态
                // TODO 新增推荐人推荐成功奖励会员天数字段 / 佣金比例字段
                TeaTopup teaTopup = teaTopupService.selectTeaTopupByOrderId(notifyResult.getOutTradeNo());
                teaTopup.setOrderStatus("0");
                teaTopup.setRemark(teaTopup.getRemark() + "\n" + "反馈: " + xmlData);
                teaTopup.setUpdateTime(new Date());
                // 需要增加一个支付成功时间和微信反馈报文
                teaTopup.setSuccessTime(new Date());
                teaTopup.setRespContent(String.valueOf(notifyResult));
                teaTopupService.updateTeaTopup(teaTopup);
                // 更新用户会员信息
                Long renewId = teaTopup.getRenewId();
                TeaRenew teaRenew = teaRenewService.selectTeaRenewById(renewId);
                // 需要增加一个会员项目增加天数字段
                Integer day = Math.toIntExact(teaRenew.getRenewDay());

                TeaMember teaMember = teaMemberService.selectTeaMemberById(teaTopup.getMemberId());
                Date memberExpireDate = teaMember.getMemberExpireDate();
                if (memberExpireDate != null && memberExpireDate.after(new Date())) {
                    log.info("会员还未过期, 在会员基础上加{}天", day);
                    Calendar calendar = new GregorianCalendar();
                    calendar.setTime(memberExpireDate); //类型转换
                    calendar.add(calendar.DATE, day);//会员增加天数
                    // 设置时分秒
                    calendar.set(Calendar.HOUR_OF_DAY, 23); // 设置小时（24小时制）
                    calendar.set(Calendar.MINUTE, 59); // 设置分钟
                    calendar.set(Calendar.SECOND, 59); // 设置秒
                    Date newMemberExpireDate = calendar.getTime();
                    teaMember.setMemberExpireDate(newMemberExpireDate);
                } else {
                    log.info("会员已过期, 在当前时间加{}天", day);
                    Date date = new Date();
                    Calendar calendar = new GregorianCalendar();
                    calendar.setTime(date); //类型转换
                    calendar.add(calendar.DATE, day);//会员增加天数
                    // 设置时分秒
                    calendar.set(Calendar.HOUR_OF_DAY, 23); // 设置小时（24小时制）
                    calendar.set(Calendar.MINUTE, 59); // 设置分钟
                    calendar.set(Calendar.SECOND, 59); // 设置秒
                    Date newMemberExpireDate = calendar.getTime();
                    teaMember.setMemberExpireDate(newMemberExpireDate);
                }
                teaMember.setDisable("1");
                teaMember.setRenewalTime(new Date());
                teaMemberService.updateTeaMember(teaMember);
                // TODO 用户支付成功后，需要查看是否有推荐人，有推荐人要给推荐人相关奖励（奖励会员权益10天等）
                // TODO 同时记录奖励记录
                String superReferralCode = teaMember.getSuperReferralCode();
                if (StringUtils.isNotBlank(superReferralCode)) {
                    log.info("上级推荐人{} 不为空，查询上级推荐人并给予奖励", superReferralCode);
                    TeaMember superMember = teaMemberService.selectTeaMemberByReferralCode(superReferralCode);
                    log.info("该会员有推荐人，则奖励推荐人{}", superReferralCode);
                    String rewardType = teaRenew.getRewardType(); // 奖励类型(0：天，1：佣金)
                    Long awardRefereesDays = teaRenew.getAwardRefereesDays(); // 奖励推荐人天数
                    if (StringUtils.equals(rewardType, "0")) {
                        // 天数
                        Long extractableDays = superMember.getExtractableDays(); // 上级推荐人可提现天数
                        if (extractableDays != null) {
                            superMember.setExtractableDays(extractableDays + awardRefereesDays);
                        } else {
                            superMember.setExtractableDays(awardRefereesDays);
                        }
                        teaMemberService.updateTeaMember(superMember);
                        log.info("上级推荐人奖励成功, 同时记录奖励日志...");
                        TeaRewardRecord supperRewardRecord = new TeaRewardRecord();
                        supperRewardRecord.setUserId(superMember.getUserId());
                        supperRewardRecord.setRewardDate(new Date());
                        supperRewardRecord.setRewardDay(awardRefereesDays);
                        supperRewardRecord.setRewardType("0"); // 类型为奖励 (0:奖励, 1:兑换)
                        supperRewardRecord.setRewardSource("推荐奖励");
                        supperRewardRecord.setRemark(String.format("推荐用户开通会员成功，奖励%s天会员使用权限!", awardRefereesDays));
                        teaRewardRecordService.insertTeaRewardRecord(supperRewardRecord);
                        log.info("奖励记录成功！");
                    } else {
                        log.warn("未设置的奖励类型：{}", rewardType);
                    }
                }
            }
            return WxPayNotifyResponse.success("成功");
        } catch (Exception ex) {
            log.error("接收微信支付反馈结果异常：{}", ex.getMessage());
            log.error(ex.getMessage(), ex);
            return WxPayNotifyResponse.failResp("失败");
        }
    }

    @Override
    public AjaxResult getProductHisList(Long productId, Long day) {
        try {
            log.info("根据产品id{} 查询该产品历史数据{} 信息", productId, day);
            JSONObject result = JSONUtil.createObj();
            List<TeaPriceDetails> list = teaPriceDetailsService.selectTeaPriceDetailsListByProductIdAndDay(productId, day);
            result.putOpt("list", list);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            if (list != null && list.size() > 0) {
                List<String> times = new ArrayList<>();
                List<String> price = new ArrayList<>();

                if (list.size() > 7 && day > 7) {
                    log.info("数组和天数都大于7");
                    Integer model = (list.size() / 7);
                    List<List<TeaPriceDetails>> lists = StringUtils.splitList(list, model);
                    for (List<TeaPriceDetails> details : lists) {
                        Date createTime = details.get(0).getCreateTime();
                        BigDecimal productPrice = details.get(0).getProductPrice();
                        times.add(sdf.format(createTime));
                        price.add(productPrice.toString());
                    }
                } else {
                    log.info("数组和天数有一个小于7");
                    for (TeaPriceDetails detail : list) {
                        times.add(sdf.format(detail.getCreateTime()));
                        price.add(detail.getProductPrice().toString());
                    }
                }
                Collections.reverse(times);
                Collections.reverse(price);
                result.put("times", times);
                result.put("price", price);
            }
            return AjaxResult.success(result);
        } catch (JSONException e) {
            log.error("根据产品id{} 查询该产品历史数据{} 信息出现异常：{}", productId, day, e.getMessage());
            log.error(e.getMessage(), e);
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult createProductHisEchart(Long productId, Long day) {
        try {
            log.info("根据产品id{} 查询该产品历史数据{} 信息", productId, day);
            JSONObject result = JSONUtil.createObj();
            List<TeaPriceDetails> list = teaPriceDetailsService.selectTeaPriceDetailsListByProductIdAndDay(productId, day);
            result.putOpt("list", list);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            List<String> times = new ArrayList<>();
            List<String> price = new ArrayList<>();
            if (list != null && list.size() > 0) {

                if (list.size() > 7 && day > 7) {
                    log.info("数组和天数都大于7");
                    Integer model = (list.size() / 7);
                    List<List<TeaPriceDetails>> lists = StringUtils.splitList(list, model);
                    for (List<TeaPriceDetails> details : lists) {
                        Date createTime = details.get(0).getCreateTime();
                        BigDecimal productPrice = details.get(0).getProductPrice();
                        times.add(sdf.format(createTime));
                        price.add(productPrice.toString());
                    }
                } else {
                    log.info("数组和天数有一个小于7");
                    for (TeaPriceDetails detail : list) {
                        times.add(sdf.format(detail.getCreateTime()));
                        price.add(detail.getProductPrice().toString());
                    }
                }
                Collections.reverse(times);
                Collections.reverse(price);
                result.put("times", times);
                result.put("price", price);
            }
            Double max = 8d;
            Double min = 1d;
            Double limit = 1d;
            if (price != null && price.size() > 0) {
                max = Double.valueOf(Collections.max(price));
                min = Double.valueOf(Collections.min(price));
                limit = (max - min) / 2;
                max += limit;
                min -= limit;
            }


            //如 果不使用Font,中文将显示不出来
            Font font = new Font("新宋体", Font.BOLD, 10);
            // 创建数据
            Map<String, Map<String, String>> datas = new LinkedHashMap<String, Map<String, String>>();

            for (int i = 0; i < times.size(); i++) {
                Map<String, String> map = new LinkedHashMap<>();
                map.put("明细记录", price.get(i));
                datas.put(times.get(i), map);
            }

            JFreeChart chart = createLineChart("历史明细-时间曲线",
                    datas,
                    "时间",
                    "金额(元)",
                    font,
                    max,
                    min,
                    limit);
            //在D盘目录下生成图片
            String uploadPath = TeawineConfig.getUploadPath() + File.separator + "echartData";
            File p = new File(uploadPath);
            if (!p.exists()) {
                p.mkdirs();
            }
            String imageName = System.currentTimeMillis() + "_data" + ".png";
            File file = new File(p.getPath() + "/" + imageName);
            try {
                if (file.exists()) {
                    file.delete();
                }
                ChartUtilities.saveChartAsPNG(file, chart, 800, 600);
                // 读取图片文件到字节数组
                Path path = file.toPath();
                byte[] imageBytes = Files.readAllBytes(path);

                // 对字节数组进行Base64编码
                String base64ImageString = "data:image/png;base64," + Base64.getEncoder().encodeToString(imageBytes);
                result.put("image", base64ImageString);
                // 删除已生成base64的文件
                // file.delete();
            } catch (IOException e) {
                log.info("生成base64出现异常：{}", e.getMessage());
                log.info(e.getMessage(), e);
            }
            return AjaxResult.success(result);
        } catch (Exception e) {
            log.error("根据产品id{} 查询该产品历史数据{} 信息出现异常：{}", productId, day, e.getMessage());
            log.error(e.getMessage(), e);
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    public AjaxResult addOrRemoveFocus(Long productId) {
        try {
            log.info("添加或移除我的关注: {}", productId);
            Long userId = SecurityUtils.getUserId();
            // Long userId = 1l;
            TeaFocus teaFocus = teaProductService.selectFocusByProductIdAndUserId(productId, userId);
            Integer success = 0;
            if (teaFocus != null) {
                log.info("移除产品id为{} 的关注", productId);
                success = teaProductService.removeFocusByProductIdAndUserId(productId, userId);
            } else {
                log.info("新增产品id为{} 的关注", productId);
                success = teaProductService.addTeaFocus(productId, userId);
            }
            if (success > 0) {
                return AjaxResult.success("操作成功");
            }
        } catch (Exception e) {
            log.error("添加或移除我的关注出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            return AjaxResult.error(e.getMessage());
        }
        return AjaxResult.success("操作失败");
    }

    @Override
    public AjaxResult removeFacusList(List<Long> productIds) {
        try {
            log.info("添加或移除我的关注: {}", productIds);
            Long userId = SecurityUtils.getUserId();
            // Long userId = 1l;
            log.info("移除产品id为{} 的关注", productIds);
            Integer success = teaProductService.removeFocusByProductIdsAndUserId(productIds, userId);
            if (success > 0) {
                return AjaxResult.success("操作成功");
            }
        } catch (Exception e) {
            log.error("批量移除我的关注出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            return AjaxResult.error(e.getMessage());
        }
        return AjaxResult.error("操作失败");
    }

    @Override
    public AjaxResult importDetails(InUpDetailsVo detailsVo) {
        try {
            List<Long> ids = detailsVo.getIds();
            log.info("导入产品到产品明细处:{}", ids);
            Long userId = SecurityUtils.getUserId();
            // Long userId = 1l;
            List<TeaProduct> proList = teaProductService.selectListByProductIdsAndUserId(ids, userId);
            List<Long> detProIds = teaDetailsService.selectTeaDetailsListByPruductsAndUserId(ids, userId);
            List<TeaDetails> list = new ArrayList<>();
            if (detProIds != null && detProIds.size() > 0) {
                log.info("去重重复数据入库");
                for (TeaProduct teaProduct : proList) {
                    boolean isHas = detProIds.contains(teaProduct.getId());
                    if (!isHas) {
                        // 不含有该产品，则插入, 反之不做操作
                        TeaDetails teaDetails = new TeaDetails();
                        teaDetails.setProductId(teaProduct.getId());
                        teaDetails.setProductName(teaProduct.getProductName());
                        teaDetails.setAmount(1l);
                        teaDetails.setTotalPrice(teaProduct.getProductPrice());
                        teaDetails.setUnitPrice(teaProduct.getProductPrice());
                        teaDetails.setCreateTime(new Date());
                        teaDetails.setUserId(userId);
                        list.add(teaDetails);
                    }
                }
            } else {
                log.info("全是新数据, 批量插入到明细表");
                for (TeaProduct teaProduct : proList) {
                    TeaDetails teaDetails = new TeaDetails();
                    teaDetails.setProductId(teaProduct.getId());
                    teaDetails.setProductName(teaProduct.getProductName());
                    teaDetails.setAmount(1l);
                    teaDetails.setTotalPrice(teaProduct.getProductPrice());
                    teaDetails.setUnitPrice(teaProduct.getProductPrice());
                    teaDetails.setCreateTime(new Date());
                    teaDetails.setUserId(userId);
                    list.add(teaDetails);
                }
            }
            // 导入到产品明细表
            if (list != null && list.size() > 0) {
                log.info("共需导入{}条数据", list.size());
                teaDetailsService.insertTeaDetailsList(list);
            } else {
                log.info("处理后无数据需要导入！");
            }
            return AjaxResult.success("导入成功");
        } catch (Exception e) {
            log.error("导入产品明细出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    @Transactional
    public AjaxResult inUpDetails(InUpDetailsVo detailsVo) {
        try {
            log.info("批量新增/修改产品明细");
            Long userId = SecurityUtils.getUserId();
            List<TeaDetails> teaDetails = detailsVo.getDetails();
            if (teaDetails != null && teaDetails.size() > 0) {
                for (TeaDetails teaDetail : teaDetails) {
                    if (teaDetail.getId() == null) {
                        log.info("这是需要新增的数据!");
                        teaDetail.setUserId(userId);
                        teaDetailsService.insertTeaDetails(teaDetail);
                    } else {
                        log.info("这是需要修改的数据!");
                        teaDetailsService.updateTeaDetails(teaDetail);
                    }
                }
            }
            return AjaxResult.success("操作成功");
        } catch (Exception e) {
            log.error("批量新增/修改产品明细出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            return AjaxResult.error(e.getMessage());
        }
    }

    @Override
    @Transactional
    public AjaxResult updateDetails(List<TeaDetails> teaDetails) {
        if (teaDetails != null && teaDetails.size() > 0) {
            for (TeaDetails teaDetail : teaDetails) {
                teaDetailsService.updateTeaDetails(teaDetail);
            }
        }
        return AjaxResult.success();
    }

    @Override
    @Transactional
    public AjaxResult withdrawAccount(Long day) {
        Long userId = SecurityUtils.getUserId();
        TeaMember teaMember = teaMemberService.selectTeaMemberByUserId(userId);
        if (teaMember != null && teaMember.getExtractableDays() != null) {
            if (day > teaMember.getExtractableDays()) {
                log.info("提取天数大于实有可提取天数，参数错误！");
                return AjaxResult.error("提取天数大于实有可提取天数，参数错误！");
            }
            // 剩余可提取天数
            Long residualExtractableDays = (teaMember.getExtractableDays() - day);
            teaMember.setExtractableDays(residualExtractableDays);
            // 已提取天数
            if (teaMember.getDrawnDays() != null) {
                Long drawnDays = teaMember.getDrawnDays() + day;
                teaMember.setDrawnDays(drawnDays);
            } else {
                teaMember.setDrawnDays(day);
            }
            // 将提取天数设置到会员天数内
            Date memberExpireDate = teaMember.getMemberExpireDate();
            if (memberExpireDate != null && memberExpireDate.after(new Date())) {
                log.info("会员还未过期, 在会员基础上加{}天", day);
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(memberExpireDate); //类型转换
                calendar.add(calendar.DATE, day.intValue());//会员增加天数
                // 设置时分秒
                calendar.set(Calendar.HOUR_OF_DAY, 23); // 设置小时（24小时制）
                calendar.set(Calendar.MINUTE, 59); // 设置分钟
                calendar.set(Calendar.SECOND, 59); // 设置秒
                Date newMemberExpireDate = calendar.getTime();
                teaMember.setMemberExpireDate(newMemberExpireDate);
            } else {
                log.info("会员已过期, 在当前时间加{}天", day);
                Date date = new Date();
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(date); //类型转换
                calendar.add(calendar.DATE, day.intValue());//会员增加天数
                // 设置时分秒
                calendar.set(Calendar.HOUR_OF_DAY, 23); // 设置小时（24小时制）
                calendar.set(Calendar.MINUTE, 59); // 设置分钟
                calendar.set(Calendar.SECOND, 59); // 设置秒
                Date newMemberExpireDate = calendar.getTime();
                teaMember.setMemberExpireDate(newMemberExpireDate);
            }
            teaMember.setDisable("1");
            teaMember.setRenewalTime(new Date());
            teaMemberService.updateTeaMember(teaMember);
            // 提现奖励记录在案
            TeaRewardRecord teaRewardRecord = new TeaRewardRecord();
            teaRewardRecord.setRewardType("1"); // 类型为兑换
            teaRewardRecord.setUserId(userId);
            teaRewardRecord.setRewardDay(day);
            teaRewardRecord.setRewardDate(new Date());
            teaRewardRecord.setRewardSource("提现兑换");
            teaRewardRecord.setRemark(String.format("提现兑换%s天的会员使用权限", day));
            teaRewardRecordService.insertTeaRewardRecord(teaRewardRecord);
            log.info("兑换成功！");
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult setLimitedExperience() {
        log.info("看广告得限时体验，结果处理!");
        TeaAdvertisConfig teaAdvertisConfig = teaAdvertisConfigService.selectActiviteTeaAdvertisConfig();
        if (teaAdvertisConfig != null) {
            Long experienceTime = teaAdvertisConfig.getExperienceTime(); // 体验时间

            Long userId = SecurityUtils.getUserId();
            TeaMember teaMember = teaMemberService.selectTeaMemberByUserId(userId);
            Date memberExpireDate = teaMember.getMemberExpireDate();
            if (memberExpireDate == null) {
                log.info("白纸用户, 新增{}分钟会员体验权限！", experienceTime);
            }
            if (memberExpireDate == null || (teaMember.getDisable() != "1" && memberExpireDate.before(new Date()))) {
                log.info("过期会员/白纸用户, 新增{}分钟会员体验权限！", experienceTime);
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(new Date()); //类型转换
                // 设置分秒
                calendar.add(Calendar.MINUTE, experienceTime.intValue()); // 增加会员体验时间（分钟）
                calendar.set(Calendar.SECOND, 59); // 设置秒
                Date newMemberExpireDate = calendar.getTime();
                teaMember.setMemberExpireDate(newMemberExpireDate);
            } else {
                log.info("正式会员, 不做任何处理");
            }
            teaMember.setDisable("1");
            teaMember.setRenewalTime(new Date());
            teaMemberService.updateTeaMember(teaMember);
            log.info("广告奖励会员体验已发放！");
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult getInvitationUserData() {
        log.info("获取当前用户已邀请的用户数量...");
        Long userId = SecurityUtils.getUserId();
        Integer userNum = 0;
        userNum = teaMemberService.getInvitationUserData(userId);
        if (userNum > 5) {
            log.info("已邀请5位好友并奖励过，不再计数!");
        }
        return AjaxResult.success();
    }

    /**
     * @param openId      微信用户openId
     * @param outTradeNo  我们的系统订单编号
     * @param amount      付款金额
     * @param description 商品描述
     * @param type        付款类型 详见PayTypeEnumConst
     * @Description: 向微信服务器发起预付款订单
     * @Return: java.util.Map<java.lang.String, java.lang.Object>
     */
    public Map<String, Object> createWxOrderToWxService(String openId, String outTradeNo, Integer amount, String description, String type) throws Exception {
        final WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder()
                //调起支付的人的 openId
                .openid(openId)
                //订单编号
                .outTradeNo(outTradeNo)
                //订单金额
                .totalFee(amount)
                //商品描述
                .body(description)
                //获取本地IP
                .spbillCreateIp(InetAddress.getLoopbackAddress().getHostAddress())
                .attach(type)
                //回调的 URL 地址  已经在WxConfig文件中进行设置
                .build();
        WxPayMpOrderResult result = this.wxPayService.createOrder(wxPayUnifiedOrderRequest);
        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("appId", result.getAppId());
        returnMap.put("nonceStr", result.getNonceStr());
        returnMap.put("packageValue", result.getPackageValue());
        returnMap.put("paySign", result.getPaySign());
        returnMap.put("signType", result.getSignType());
        returnMap.put("timeStamp", result.getTimeStamp());
        returnMap.put("orderId", outTradeNo);
        log.info("微信订单创建成功：{}", outTradeNo);
        return returnMap;
    }


    /**
     * 生成折线图
     *
     * @param title
     * @param data
     * @param type
     * @param unit
     * @param font
     * @return
     */
    public static JFreeChart createLineChart(String title,
                                             Map<String, Map<String, String>> data,
                                             String type,
                                             String unit,
                                             Font font,
                                             Double max,
                                             Double min,
                                             Double limit) {
        try {
            DefaultCategoryDataset ds = new DefaultCategoryDataset();
            Set<Map.Entry<String, Map<String, String>>> set1 = data.entrySet();
            Iterator iterator1 = set1.iterator();
            Iterator iterator2;
            HashMap<String, String> map;
            Set<Map.Entry<String, String>> set2;
            Map.Entry entry1;
            Map.Entry entry2;
            while (iterator1.hasNext()) {
                entry1 = (Map.Entry) iterator1.next();
                map = (HashMap<String, String>) entry1.getValue();
                set2 = map.entrySet();
                iterator2 = set2.iterator();
                while (iterator2.hasNext()) {
                    entry2 = (Map.Entry) iterator2.next();
                    ds.setValue(Double.parseDouble(entry2.getValue().toString()), entry2.getKey().toString(), entry1.getKey().toString());
                }
            }

            //创建折线图,折线图分水平显示和垂直显示两种
            // //2D折线图
            JFreeChart chart = ChartFactory.createLineChart(title, type, unit, ds, PlotOrientation.VERTICAL, true, true, true);
            // //3D折线图
            JFreeChart chart2 = ChartFactory.createLineChart3D(title, type, unit, ds, PlotOrientation.VERTICAL, true, true, false);

            //设置整个图片的标题字体
            chart.getTitle().setFont(font);

            //设置提示条字体
            font = new Font("宋体", Font.BOLD, 10);
            chart.getLegend().setItemFont(font);

            //得到绘图区
            CategoryPlot plot = (CategoryPlot) chart.getPlot();
            //得到绘图区的域轴(横轴),设置标签的字体
            plot.getDomainAxis().setLabelFont(font);
            NumberAxis numberAxis = (NumberAxis) plot.getRangeAxis();
            // 设置Y轴的最小值
            numberAxis.setLowerBound(min);

            // 设置Y轴的最大值
            numberAxis.setUpperBound(max);

            // 设置Y轴的刻度间隔
            numberAxis.setTickUnit(new NumberTickUnit(limit));

            // 设置背景透明度
            plot.setBackgroundAlpha(0.0f);
            // 设置网格横线颜色
            plot.setRangeGridlinePaint(Color.lightGray);
            // 设置网格横线大小
            plot.setDomainGridlineStroke(new BasicStroke(0.2F));
            plot.setRangeGridlineStroke(new BasicStroke(0.2F));

            //设置横轴标签项字体
            plot.getDomainAxis().setTickLabelFont(font);

            // 生成折线图上的数字
            //绘图区域(红色矩形框的部分)
            LineAndShapeRenderer lineAndShapeRenderer = (LineAndShapeRenderer) plot.getRenderer();
            lineAndShapeRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
            //设置图表上的数字可见
            lineAndShapeRenderer.setBaseItemLabelsVisible(true);
            //设置图表上的数字字体
            lineAndShapeRenderer.setBaseItemLabelFont(new Font("宋体", Font.BOLD, 10));

            //设置折线图拐角上的正方形
            //创建一个正方形
            Rectangle shape = new Rectangle(4, 4);
            lineAndShapeRenderer.setSeriesShape(0, shape);
            //设置拐角上图形可见
            lineAndShapeRenderer.setSeriesShapesVisible(0, true);

            // 获取显示线条的对象
            LineAndShapeRenderer lasp = (LineAndShapeRenderer) plot.getRenderer();
            // 设置拐点是否可见/是否显示拐点
            lasp.setBaseShapesVisible(true);
            // 设置拐点不同用不同的形状
            lasp.setDrawOutlines(true);
            // 设置线条是否被显示填充颜色
            lasp.setUseFillPaint(true);
            // 设置拐点颜色
            lasp.setBaseFillPaint(Color.blue);//蓝色


            //设置范围轴(纵轴)字体
            font = new Font("宋体", Font.BOLD, 10);
            plot.getRangeAxis().setLabelFont(font);
//            plot.setForegroundAlpha(1.0f);
            return chart;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
